package rursu.view;

import java.util.ArrayList;
import java.util.List;

import rursu.business.MovieApplication;
import rursu.business.R;
import rursu.business.pojo.Movie;
import rursu.providers.ImageProvider;
import rursu.providers.MovieArrayAdapter;
import rursu.providers.MoviesListCallback;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.ProgressBar;

public class BaseMoviesFragment extends Fragment implements MoviesListCallback {

	protected ListView listView;
	protected MovieArrayAdapter adapter;
	private View view;
	private ProgressBar progress;
	private final String LOGGER_TAG = BaseMoviesFragment.class.getCanonicalName();
	private int firstVisibleItemOld;
	private int visibleItemCountOld;
	protected boolean isFirstShow = true;
	ImageProvider imageProvider;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		imageProvider = ((MovieApplication) getActivity().getApplication()).getImageProviderManager();
		setHasOptionsMenu(true);
	}

	@Override
	public void onResume() {
		super.onResume();

		isFirstShow = true;
		Log.d(LOGGER_TAG, "onResume launched");

	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		view = inflater.inflate(R.layout.movies_fragment, container, false);
		progress = (ProgressBar) inflater.inflate(R.layout.progress_layout, container, false);

		listView = (ListView) view.findViewById(R.id.list_fragment);
		final ImageProvider imageProvider = ((MovieApplication) getActivity().getApplication()).getImageProviderManager();

		listView.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> parent, View view,int position, long id) {

				imageProvider.stopLoading();
				firstVisibleItemOld = 0;
				visibleItemCountOld = 0;

				Movie movie = (Movie) parent.getItemAtPosition(position);
				((MainActivity) getActivity()).showMovieDetails(movie);
			}

		});

		listView.setOnScrollListener(new OnScrollListener() {

			public void onScrollStateChanged(AbsListView view, int scrollState) {

				int firstVisibleItem = listView.getFirstVisiblePosition();
				int totalItemCount = listView.getAdapter().getCount();
				int visibleItemCount = Math.abs(listView.getLastVisiblePosition() - firstVisibleItem) + 1;

				if (scrollState == SCROLL_STATE_IDLE) {

					showImages(firstVisibleItem, visibleItemCount, totalItemCount);

				}
			}

			public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

				if (isFirstShow && visibleItemCount > 0) {
					isFirstShow = false;

					showImages(firstVisibleItem, visibleItemCount,totalItemCount);
				}
			}
		});

		adapterInit();

		return view;
	}

	protected void adapterInit() {
		
		if (adapter == null) {							
			((MovieApplication) getActivity().getApplication()).getDataProviderManager().getRecentMovies(this);
			
		} else {
			listView.setAdapter(adapter);
		}
	}

	public void onPreDownload() {
		listView.setEmptyView(progress);
		listView.invalidate();
	}

	@Override
	public void onPause() {
		super.onPause();
		ImageProvider imageProvider = ((MovieApplication) getActivity().getApplication()).getImageProviderManager();
		imageProvider.stopLoading();
	}

	public void onDownloaded(List<Movie> movies) {

		if (!movies.isEmpty()) {

			adapter = new MovieArrayAdapter(getActivity(), R.layout.item_layout, movies);

			listView.setAdapter(adapter);

			int firstVisibleItem = listView.getFirstVisiblePosition();
			int totalItemCount = listView.getAdapter().getCount();
			int lastVisiblePosition = 0;
			
			if (listView.getLastVisiblePosition() >= 0) {
				lastVisiblePosition = listView.getLastVisiblePosition();
			}	
			
			int visibleItemCount = Math.abs(lastVisiblePosition - firstVisibleItem) + 1;

			showImages(firstVisibleItem, visibleItemCount, totalItemCount);
		}
	}

	public void onFailure() {
		// TODO Auto-generated method stub

	}

	private void showImages(int firstVisibleItem, int visibleItemCount,
			int totalItemCount) {

		if ((firstVisibleItem != firstVisibleItemOld) || (visibleItemCountOld != visibleItemCount)) {

			List<Movie> moviesToShow = new ArrayList<Movie>();
			List<Movie> moviesToHide = new ArrayList<Movie>();

			// accumulate movies to show
			for (int position = firstVisibleItem; position < firstVisibleItem + visibleItemCount; position++) {
				Movie movie = adapter.getItem(position);
				if (movie.getPoster() == null) {
					moviesToShow.add(movie);
				}
			}

			// accumulate movies to hide
			for (int position = 0; position < firstVisibleItem; position++) {
				moviesToHide.add(adapter.getItem(position));
			}

			for (int position = firstVisibleItem + visibleItemCount; position < totalItemCount; position++) {
				moviesToHide.add(adapter.getItem(position));
			}

			// show image of those movies
			imageProvider.stopLoading();
			imageProvider.getMoviesThumbnail(moviesToShow, adapter);

			// dispose resources for movies that should not be shown
			for (Movie movie : moviesToHide) {

				Bitmap bitmap = movie.getPoster();

				if (bitmap != null) {
					bitmap.recycle();
					movie.setPoster(null);
				}
			}

			// assign new values
			firstVisibleItemOld = firstVisibleItem;
			visibleItemCountOld = visibleItemCount;
		}
	}	
	
}
